package com.yangyang.ralearn.net.message;

import groovy.ui.Console;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.jboss.netty.buffer.ChannelBuffers;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.yangyang.ralearn.client.rlclient.Ralearn;
import com.yangyang.ralearn.common.Constants;
import com.yangyang.ralearn.net.load.ILoad;
import com.yangyang.ralearn.net.serialize.ISerizlizable;
import com.yangyang.ralearn.net.serialize.SerializeEntity;

@Component
public class MessageFactory implements ILoad {

	private static MessageFactory instance;

	private Map<Integer, Class<? extends AbstractMessage>> mapId2Messsage;

	public MessageFactory() {
		MessageFactory.instance = this;
	}

	public static MessageFactory instance() {
		if (instance == null)
			instance = new MessageFactory();
		return instance;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	@SuppressWarnings("unchecked")
	@Override
	public void onLoad(ApplicationContext context) {
		// TODO Auto-generated method stub
		this.mapId2Messsage = new HashMap<Integer, Class<? extends AbstractMessage>>();
		Map<String, Object> map = context.getBeansWithAnnotation(Message.class);
		for (Entry<String, Object> entry : map.entrySet()) {
			// Logger.getLogger(Ralearn.class).debug(entry.getKey());
			// Logger.getLogger(Ralearn.class).debug(entry.getValue());
			Class<? extends AbstractMessage> clazz = (Class<? extends AbstractMessage>) entry
					.getValue().getClass();
			// 顺便生成序列化的结构信息
			Message message = clazz.getAnnotation(Message.class);
			if (message != null) {
				for (int id : message.id()) {
					if (entry.getValue() instanceof ISerizlizable) {
						AbstractMessage value = (AbstractMessage) entry
								.getValue();
						value.setId(id);
						SerializeEntity.serialize(
								ChannelBuffers.dynamicBuffer(), value,
								(Integer[]) null);

					}
					Logger.getLogger(MessageFactory.class).debug(
							"loading message:" + entry.getKey() + ", id:" + id);
					this.mapId2Messsage.put(id, clazz);
				}
			}
		}
	}

	public AbstractMessage createMessage(int messageId) {
		if (this.mapId2Messsage.containsKey(messageId)) {
			AbstractMessage message = null;
			try {
				message = this.mapId2Messsage.get(
						messageId / Constants.MESSAGEBASE).newInstance();
				message.setId(messageId);

			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return message;

		} else {
			Logger.getLogger(MessageFactory.class).error(
					"no message defined with message id :" + messageId);
			return null;
		}
	}

}
